#include "device.h"
#include "component.h"
#include "motor_big.h"

/* 调试打印接口 */
#define LOCKBIG_LOG(format, ...)  __OSAL_LOG("[lockbig.c] " C_PURPLE format C_NONE, ##__VA_ARGS__)


/* 电机电流采集的ADC通道 */
#define LOCKBIG_DCI_ADC_CHANNEL					vADC_1
/* 计数器 */
#define IRQ_VHW_LOCKBIG_COUNTER					vCOUNTER_0

/* 事件 */
#define EVENT_MOTOR_MONITOR                     (0X00000001)  //电机监控事件

/* 电机控制参数 */
#define MOTOR_PARAM_DCI_OVERFLOW_SMALL          2500    //小扭力堵转电流2500mA
#define MOTOR_PARAM_DCI_OVERFLOW_LARGE          3500    //大扭力堵转电流3500mA

#define MOTOR_PARAM_STOP_TIME1                  1000    //电机暂停时间1（电机运行正常运行过程中状态切换需要的暂停时间）
#define MOTOR_PARAM_STOP_TIME2                  100     //电机暂停时间2（开锁堵转暂停时间、电机运行流程结束最后的暂停时间）
#define MOTOR_PARAM_TURN_TIMEOUT                9000    //电机正常运行，超时时间
#define MOTOR_PARAM_BACK_TIMEOUT                1500    //电机回拖运行，超时时间
#define MOTOR_PARAM_DCI_DETECT_DELAY_TIME       80      //电机启动后，电流检测延迟时间
#define MOTOR_PARAM_BRAKE_TIME                  30      //电机刹车时间

/* 电机监测时间间隔 */
#define MOTOR_MONITOR_TIME                      (10)    //电机监测时间间隔 10ms
/* 电机上锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_LOCKED_TIME               (1000)
/* 电机开锁堵转重新操作锁体的时间间隔 */
#define MOTOR_BLOCKED_UNLOCK_TIME               (100)  

/*上锁回拖计数器阈值*/
#define MOTOR_LOCKED_BACK_COUNTER				(75)
/*开锁回拖计数器阈值*/
#define MOTOR_UNLOCK_BACK_COUNTER				(78)

/* 锁体状态 */
static enum
{
	LOCK_STA_UNKNOW,    		//未知状态
	LOCK_STA_LOCKING,   		//正在上锁
	LOCK_STA_UNLOCKING, 		//正在开锁
	LOCK_STA_UNLOCKING_BACK, 	//正在开锁回拖
	LOCK_STA_LOCKED,    		//已上锁
	LOCK_STA_UNLOCK,    		//已开锁
}lockStatus = LOCK_STA_UNKNOW;

/* 电机状态类型 */
typedef enum
{
	MOTOR_STA_LOCKED,               //电机上锁状态：上锁
    MOTOR_STA_LOCKED_BACK,          //电机上锁状态：回拖
    MOTOR_STA_LOCKED_BRAKE,         //电机上锁状态：刹车
	MOTOR_STA_UNLOCK,               //电机开锁状态
    MOTOR_STA_UNLOCK_BRAKE,         //电机开锁状态：刹车
	MOTOR_STA_UNLOCK_BACK,          //电机开锁状态：回拖
    MOTOR_STA_STOP,                 //电机停止状态（暂停）
	MOTOR_STA_IDLE,                 //电机空闲
}MotorStatus_enum_t;

/* 电机状态数据 */
static struct
{
	volatile MotorStatus_enum_t current; //电机当前状态	
	volatile uint32_t startTime;         //电机当前状态开始时间
	volatile uint32_t timeout;           //电机当前状态超时时间
}motorStatus = {MOTOR_STA_IDLE, MOTOR_STA_IDLE};


/* 电机运行错误情况 */
volatile static enum
{
	ERR_NO_ERROR,       //无错误
	ERR_LOCK_ERROR,     //锁体错误（电机运转结束时，传感器状态不对）
	
	ERR_LOCKED_TIMEOUT, //上锁超时
	ERR_UNLOCK_TIMEOUT, //开锁超时
	ERR_BACK_TIMEOUT,   //回拖超时
	
	ERR_LOCKED_DCI,     //上锁过流
	ERR_UNLOCK_DCI,     //开锁过流
	ERR_BACK_DCI,       //回拖过流
}motorError = ERR_NO_ERROR;

/* 电机刹车原因类型 */
typedef enum
{
	MOTOR_BRAKE_NO_SOURCE,              //无刹车源
    MOTOR_BRAKE_LOCKED,                 //上锁刹车
    MOTOR_BRAKE_UNLOCK,                 //开锁刹车
}MotorBrakeSource_enum_t;

/* 上锁方向类型 */
typedef enum
{
	LOCKED_DIR_UNKNOWN,                 //未知上锁方向
    LOCKED_DIR_CW,                      //顺时针上锁方向
    LOCKED_DIR_CCW,                     //逆时针上锁方向
}Locked_Dir_enum_t;

/* 锁体控制阶段类型 */
typedef enum
{
	LOCK_CTRL_STEP_INIT,				//初始状态
	LOCK_CTRL_STEP_LOCK,				//上/开锁阶段
    LOCK_CTRL_STEP_BLOCK,				//堵转阶段
    LOCK_CTRL_STEP_BACK,                //回拖阶段
}Lock_Ctrl_Step_enum_t;

/* 锁体模式 */
typedef enum
{
    LOCKED_MODE_NORMAL,                 //普通模式
    LOCKED_MODE_TEST,                   //测试模式
}Locked_Mode_enum_t;


/* 中断挂起标志 */
volatile static uint8_t isrPendFlag;        //中断挂起标志

/* 锁体模式 */
__attribute__((unused))  static Locked_Mode_enum_t lockedMode = LOCKED_MODE_NORMAL;

/* 上锁阶段 */
static Lock_Ctrl_Step_enum_t lockedCtrlStep = LOCK_CTRL_STEP_INIT;

/* 电机配置参数 */
static struct
{
    uint8_t init_flag; //初始化标志
    uint8_t torque;    //电机扭力（1：大扭力、0：小扭力）
    uint8_t dir;       //电机方向（1：锁在门的右侧、0：锁在门的左侧）
}lock_config;



/**
  * @brief  切换电机状态
  * @note   
  *
  * @param  status：需要切换的状态
  * @param  timeout：该状态的超时时间
  */
static void LockBig_SwitchMotorStatus(MotorStatus_enum_t status, uint32_t timeout)
{
	isrPendFlag++;
	motorStatus.current = status;
	motorStatus.timeout = timeout;
	motorStatus.startTime = OSAL_GetTickCount();
	if (MOTOR_STA_LOCKED_BACK == motorStatus.current)
	{
        /* 上锁回拖 */
        MotorBig_TurnLeft();//上锁回拖操作跟开锁操作控制电机的方向是一致的
	}
    else if (MOTOR_STA_UNLOCK_BACK == motorStatus.current)
	{
        /* 开锁回拖 */
        MotorBig_TurnRight();//开锁回拖操作跟上锁操作控制电机的方向是一致的
    }
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current ||
            MOTOR_STA_UNLOCK_BRAKE == motorStatus.current )
	{
		/* 刹车 */
		MotorBig_Brake();
	}
	else if (MOTOR_STA_LOCKED == motorStatus.current)
	{
		/* 电机上锁 */
		MotorBig_TurnRight();
	}
	else if (MOTOR_STA_UNLOCK == motorStatus.current)
	{
		/* 电机开锁 */
		MotorBig_TurnLeft();
	}
	else
	{
		/* 电机停止 */
		MotorBig_Stop();
	}
	isrPendFlag--;
}

/**
  * @brief  处理上锁流程结束
  *         
  * @note   
  */
static void LockBig_MotorLockedEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIG_LOG("LockBig_MotorLockedEnd\r\n");
	/* 上锁堵塞了,执行回拖 */
	if(lockedCtrlStep == LOCK_CTRL_STEP_BLOCK)
	{
		motorError = ERR_NO_ERROR;
		lockedCtrlStep = LOCK_CTRL_STEP_BACK;		//标记为回拖阶段
		/* 设置并启动计数器,控制回拖位置 */
		Device_Write(vCOUNTER_0, NULL, 0, MOTOR_LOCKED_BACK_COUNTER);
		Device_Enable(vCOUNTER_0);
		LockBig_SwitchMotorStatus(MOTOR_STA_LOCKED_BACK, MOTOR_PARAM_BACK_TIMEOUT);
		return;
	}
	else
	{
		
	}
	Device_Disable(vCOUNTER_0);
	lockedCtrlStep = LOCK_CTRL_STEP_INIT;
	
	if(motorError == ERR_LOCKED_TIMEOUT || motorError == ERR_BACK_TIMEOUT)
	{
		lockMsg.lock = LOCK_ACTION_ABNORMAL;//锁体异常-上锁超时,上锁回拖超时
	}
	else
	{
		lockMsg.lock = LOCK_ACTION_LOCKED;//上锁成功
	}
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理开锁流程结束
  *         
  * @note   
  */
static void LockBig_MotorUnlockEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIG_LOG("LockBig_MotorUnlockEnd\r\n");
	if(motorError == ERR_UNLOCK_TIMEOUT)
	{
		lockMsg.lock = LOCK_ACTION_ABNORMAL;//锁体异常-开锁超时
	}
	else
	{
		lockMsg.lock = LOCK_ACTION_UNLOCK_NO_BACK;//开锁成功,未回拖
	}
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  处理开锁回拖流程结束
  *         
  * @note   
  */
static void LockBig_MotorUnlockBackEnd(void)
{
	LockMsg_t lockMsg;
	memset(&lockMsg, 0, sizeof(lockMsg));
	LOCKBIG_LOG("LockBig_MotorUnlockBackEnd\r\n");

	lockMsg.lock = LOCK_ACTION_UNLOCK_BACK;//开锁成功,已回拖
	OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));//消息上报
	motorError = ERR_NO_ERROR;
	motorStatus.current = MOTOR_STA_IDLE;
	OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
}

/**
  * @brief  电机运行结束处理
  *         
  * @note   
  */
static void LockBig_MotorTurnEnd(void)
{
    if (motorError == ERR_BACK_TIMEOUT || motorError == ERR_BACK_DCI)/* 产生了锁体回拖超时、回拖过流 */
	{
		LockMsg_t lockMsg;
		memset(&lockMsg, 0, sizeof(lockMsg));
        LOCKBIG_LOG("back/reset error, motorError:%d\r\n", motorError);
		if(lockStatus == LOCK_STA_UNLOCKING_BACK)
		{
			lockMsg.lock = LOCK_ACTION_ABNORMAL;			//开锁回拖过流
			OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));	//消息上报
		}
		
        OSAL_EventDelete(COMP_LOCK, EVENT_MOTOR_MONITOR);
        motorError = ERR_NO_ERROR; 
		motorStatus.current = MOTOR_STA_IDLE;
		Device_Disable(vCOUNTER_0);
    }
    else if (lockStatus == LOCK_STA_LOCKING)
	{
		/* 处理上锁流程结束 */
        LockBig_MotorLockedEnd();
    }
    else if (lockStatus == LOCK_STA_UNLOCKING)
	{
        /* 处理开锁流程结束 */
        LockBig_MotorUnlockEnd();
    }
	else if (lockStatus == LOCK_STA_UNLOCKING_BACK)
	{
        /* 处理开锁回拖流程结束 */
        LockBig_MotorUnlockBackEnd();
    }
}

/**
  * @brief  电机运行超时
  *         
  * @note   
  */
static void LockBig_MotorTimeout(void)
{
	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED:      //上锁超时
            motorError = ERR_LOCKED_TIMEOUT; 
            break;
		case MOTOR_STA_UNLOCK:      //开锁超时  
            motorError = ERR_UNLOCK_TIMEOUT; 
            break;
		case MOTOR_STA_LOCKED_BACK: //上锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
        case MOTOR_STA_UNLOCK_BACK: //开锁回拖超时
            motorError = ERR_BACK_TIMEOUT;   
            break;
		default: 
            break;
	}
    if (MOTOR_STA_STOP == motorStatus.current)	/* 电机STOP 超时 */     
	{
        LockBig_MotorTurnEnd();
    }
	else if (MOTOR_STA_LOCKED_BRAKE == motorStatus.current)
	{
		if(motorError == ERR_LOCKED_DCI)/* 上锁过流导致的刹车超时 */
		{
			LOCKBIG_LOG("ERR_LOCKED_DCI\r\n");
			LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_LOCKED_TIME);
		}
		else	/*  */
        {
			LOCKBIG_LOG("motorError != ERR_LOCKED_DCI\r\n");
            LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
        }
	}
	else if (MOTOR_STA_UNLOCK_BRAKE == motorStatus.current)
	{
		if (lockStatus == LOCK_STA_UNLOCKING)
		{
			LockBig_MotorTurnEnd(); //开锁成功仅刹车，不停车
		}
		else
		{
			if(motorError == ERR_UNLOCK_DCI)/* 开锁过流导致的刹车超时 */
			{
				LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_BLOCKED_UNLOCK_TIME);
			}
			else	/*  */
			{
				LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
			}
		}
	}
    else
    {
		/* 上锁超时、开锁超时、回拖超时、*/
        LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
    }
}

/**
  * @brief  检查电机电流
  *         
  * @note   只有以下三种电机状态，才需要检查电流：
  *         MOTOR_STA_LOCKED：上锁状态
  *         MOTOR_STA_UNLOCK：开锁状态
  *         MOTOR_STA_BACK：回拖状态
  */
static void LockBig_MotorCheckDCI(void)
{
	uint16_t dci, dci_overflow;
	uint8_t overflowCnt = 0;

	switch (motorStatus.current)
	{
		case MOTOR_STA_LOCKED: 
		case MOTOR_STA_UNLOCK: 
		case MOTOR_STA_LOCKED_BACK: 
        case MOTOR_STA_UNLOCK_BACK: 
            break;
		default: 
            return;
	}

    dci_overflow = (lock_config.torque == LOCKED_TORQUE_HIGH) ? MOTOR_PARAM_DCI_OVERFLOW_LARGE : MOTOR_PARAM_DCI_OVERFLOW_SMALL;

    do /* 有过流时：就连续获取10次电流 */
    {
        dci = (uint16_t)Device_Read(LOCKBIG_DCI_ADC_CHANNEL, NULL, 0, 0);
        dci *= 20; //mV转换成mA（电机驱动串的电阻是0.05Ω）
        overflowCnt++;
    }while (dci >= dci_overflow && overflowCnt < 10);

    LOCKBIG_LOG("dci:%d   dci_overflow:%d\r\n", dci, dci_overflow);

    if (overflowCnt >= 10)
    {
        /* 连续10次过流：标记错误情况，电机进入STOP状态 */
        if (motorStatus.current == MOTOR_STA_LOCKED)//上锁过流
        {
            motorError = ERR_LOCKED_DCI; 
            lockedCtrlStep = LOCK_CTRL_STEP_BLOCK;
            LockBig_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);//上锁过流刹车
        }
        else if (motorStatus.current == MOTOR_STA_UNLOCK)//开锁过流
        {
			motorError = ERR_UNLOCK_DCI;
//			unlockCtrlStep = LOCK_CTRL_STEP_BLOCK;
            LockBig_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);//开锁过流刹车
        }
		else if (motorStatus.current == MOTOR_STA_LOCKED_BACK)//上锁回拖过流
		{
			motorError = ERR_BACK_DCI; 
            LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);//回拖过流停止
		}
        else if (motorStatus.current == MOTOR_STA_UNLOCK_BACK)//开锁回拖过流
        {
            motorError = ERR_BACK_DCI; 
            LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);//回拖过流停止
        }
		else
        {
            LockBig_SwitchMotorStatus(MOTOR_STA_STOP, MOTOR_PARAM_STOP_TIME1);
        }
	}
}

/**
  * @brief  电机运行状态监控（电机监控事件）
  *         
  * @note   监控电机电流、超时
  *         电机状态不等于MOTOR_STA_IDLE时：该函数每间隔10ms运行一次
  */
static void LockBig_MotorMonitor(void)
{
    const uint32_t xTicks = OSAL_GetTickCount();
    uint32_t pastTime;
    pastTime = OSAL_PastTime(xTicks, motorStatus.startTime);    
	if (pastTime >= motorStatus.timeout)
	{
		LockBig_MotorTimeout();    /* 处理电机当前状态超时 */
	}
	else if (pastTime >= MOTOR_PARAM_DCI_DETECT_DELAY_TIME)
	{
		LockBig_MotorCheckDCI();   /* 检查电机运行电流（DCI） */
	}
}

/**
  * @brief  上锁接口函数
  *         
  * @note   
  */
static ErrorStatus LockBig_Locked(void)
{
	lockStatus = LOCK_STA_LOCKING;
	lockedCtrlStep = LOCK_CTRL_STEP_LOCK;
	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBig_SwitchMotorStatus(MOTOR_STA_LOCKED, MOTOR_PARAM_TURN_TIMEOUT);
	return SUCCESS;
}

/**
  * @brief  开锁接口函数
  *         
  * @note   
  */
static ErrorStatus LockBig_Unlock(void)
{
	lockStatus = LOCK_STA_UNLOCKING;
	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBig_SwitchMotorStatus(MOTOR_STA_UNLOCK, MOTOR_PARAM_TURN_TIMEOUT);
	return SUCCESS;
}

/**
  * @brief  开锁回拖接口函数
  *         
  * @note   
  */
static ErrorStatus LockBig_Unlock_Back(void)
{	
	lockStatus = LOCK_STA_UNLOCKING_BACK;
	
	/* 设置并启动计数器,控制回拖位置 */
	Device_Write(vCOUNTER_0, NULL, 0, MOTOR_UNLOCK_BACK_COUNTER);
	Device_Enable(vCOUNTER_0);

	OSAL_EventRepeatCreate(COMP_LOCK, EVENT_MOTOR_MONITOR, MOTOR_MONITOR_TIME, EVT_PRIORITY_HIGH);
	LockBig_SwitchMotorStatus(MOTOR_STA_UNLOCK_BACK, MOTOR_PARAM_TURN_TIMEOUT);
	return SUCCESS;
}

/* Lock组件API函数类型 */
static ErrorStatus Lock_Ctrl_Sub(LockCtrl_enum_t ctrl)
{
    LockMsg_t lockMsg;
    memset(&lockMsg, 0, sizeof(lockMsg));
    lockedMode = LOCKED_MODE_NORMAL;//标记为正常模式
    LOCKBIG_LOG("Lock_Ctrl, ctrl = %d\r\n", ctrl);

    if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下报锁体繁忙,不能执行锁体操作
    {
        lockMsg.lock = LOCK_ACTION_BUSY;
        OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));
        LOCKBIG_LOG("LOCK_ACTION_BUSY\r\n");
        return ERROR;
    }

    /* 变量置位 */
	lockedCtrlStep = LOCK_CTRL_STEP_INIT;
//	unlockCtrlStep = LOCK_CTRL_STEP_INIT;
	
    switch((uint8_t)ctrl)
    {
        case LOCK_CTRL_LOCKED:
			LockBig_Locked();
            break;
        case LOCK_CTRL_UNLOCK:
			LockBig_Unlock();
            break; 
		case LOCK_CTRL_UNLOCK_BACK:
			LockBig_Unlock_Back();
            break; 
        default:
            break;
    }
    return SUCCESS;
}

/* 设置上锁方向的接口 */
static ErrorStatus LockBig_SetDir_Sub(LockedDir_enum_t ctrl)
{
	LOCKBIG_LOG("LockBig_SetDir: %d\r\n", ctrl);
	MotorBig_SetDirection((uint8_t)ctrl);
	lock_config.dir = (uint8_t)ctrl;
    OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
	return SUCCESS;
}

/* 设置电机扭力的接口 */
static ErrorStatus LockBig_SetTorque_Sub(LockedTorque_enum_t torque)
{
	LOCKBIG_LOG("LockBig_SetTorque: %d\r\n", torque);
	lock_config.torque = (uint8_t)torque;
	OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
	return SUCCESS;
}

static uint16_t LockBig_HallTest(void)
{
	uint16_t startCount=0, endCount=0;
	LockMsg_t lockMsg;
	Device_Write(vCOUNTER_0, NULL, 0, 0xffff);
	Device_Enable(vCOUNTER_0);

	startCount = (uint16_t)Device_Read(vCOUNTER_0,NULL,0,NULL);
	MotorBig_TurnLeft();
	
	for(uint8_t i = 0; i < 3; i++)
	{
		OSAL_DelayUs(60000);
	}
	
	endCount = (uint16_t)Device_Read(vCOUNTER_0,NULL,0,NULL);
	MotorBig_Stop();
	Device_Disable(vCOUNTER_0);
	if(endCount - startCount > 0)
	{
		lockMsg.sensorTestStatus = 0X0A;//高速霍尔传感器检测成功
		OSAL_MessagePublish(&lockMsg, sizeof(lockMsg));	//消息上报
	}
	printf("startCount : %d, endCount : %d\r\n", startCount, endCount);
	
	return endCount - startCount;
}

/**
  * @brief  产测模式操作上锁/开锁的接口
  * @note   
  *         
  * @param  testMode：测试模式, LOCK_UNLOCK_TEST_MODE:上锁/开锁测试 MOTOR_TEST_MODE:电机测试
  * @param  data：控制参数
  * @param  dataLen:控制参数的个数
  */
static uint16_t Lock_TestCtrl_Sub(Lock_Test_Mode_enum_t testMode, uint8_t data[], uint8_t dataLen)
{
	lockedMode = LOCKED_MODE_TEST;          //标记为测试模式
	if(testMode == LOCK_UNLOCK_TEST_MODE)	//上锁/开锁测试
    {
		return 0;
	}
	else if(testMode == MOTOR_TEST_MODE)	//电机测试
    {
		if(dataLen < 1)						//电机控制至少要有一个参数
        {
            return 0;
        }
        uint8_t motorCtrl = data[0];
		switch (motorCtrl)
		{
			case 1:
				MotorBig_TurnLeft();
				break;
			case 2:
				MotorBig_TurnRight();
				break;
			case 3:
				MotorBig_Stop();
				break;
			default:
				break;
		}
		return 0;
	}
	else if(testMode == HALL_TEST_MODE)	//计数霍尔测试模式
    {
		return LockBig_HallTest();
	}
	else
	{
		return 0;
	}
}

/**
  * @brief  计数器硬件中断
  * @note   
  * @return 
  */
static void LockBig_Counter_Irq_Handler(VirtualHardware_enum_t dev, void *data, uint32_t len)
{
	Device_Disable(vCOUNTER_0);
	if (isrPendFlag != 0)
	{
        return;
    }
    isrPendFlag++;
	
	if(lockStatus == LOCK_STA_LOCKING)
	{
		LockBig_SwitchMotorStatus(MOTOR_STA_LOCKED_BRAKE, MOTOR_PARAM_BRAKE_TIME);//上锁回拖刹车
	}
	else if(lockStatus == LOCK_STA_UNLOCKING)
	{
		LockBig_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);//开锁刹车
	}
	else if(lockStatus == LOCK_STA_UNLOCKING_BACK)
	{
		LockBig_SwitchMotorStatus(MOTOR_STA_UNLOCK_BRAKE, MOTOR_PARAM_BRAKE_TIME);//开锁回拖刹车
	}

	/* 创建ISR事件 */
	OSAL_EventCreateFromISR(COMP_LOCK);
	isrPendFlag--;
}

/**
  * @brief  计数器中断处理
  * @note   
  * @return 
  */
static void LockBig_CounterIsr(void)
{
	return;
}

/**
  * @brief  锁体启动
  *         
  * @note   
  */
static void LockBig_Start(void)
{
	static uint8_t initFlag = 0;
    if (initFlag == 0)
    {
		initFlag = 1;

        OSAL_NvRead(0, &lock_config, sizeof(lock_config));
        if (lock_config.init_flag != 0xFA)
        {
            lock_config.init_flag = 0xFA; //首次上电
            lock_config.torque = LOCKED_TORQUE_SMALL;   //默认扭力：小
            lock_config.dir = LOCKED_DIR_LEFT;          //默认方向：左
            OSAL_NvWrite(0, &lock_config, sizeof(lock_config));
        }

        MotorBig_SetDirection(lock_config.dir);

		/* 注册中断回调 */
        Device_RegisteredCB(IRQ_VHW_LOCKBIG_COUNTER, LockBig_Counter_Irq_Handler);
    }
}

static void LockBig_ProcessMbox(uint8_t *msg)
{
    switch (msg[0])
    {
		case LOCK_MBOX_CTRL:
		{
			uint8_t ctrl;
			ctrl = msg[1];
			Lock_Ctrl_Sub((LockCtrl_enum_t)ctrl);
		}
			break;

		case LOCK_MBOX_SET_DIR:
		{
			uint8_t dir;
			dir = msg[1];
			LockBig_SetDir_Sub((LockedDir_enum_t)dir);
		}
			break;

		case LOCK_MBOX_SET_TORQUE:
		{
			uint8_t torque;
			torque = msg[1];
			LockBig_SetTorque_Sub((LockedTorque_enum_t)torque);
		}
			break;

		case LOCK_MBOX_TESTCTRL:
		{
			uint8_t testMode, dataLen, data[10];
			testMode = msg[1];
			dataLen = msg[2];
			memcpy(data, &msg[3], dataLen);
			Lock_TestCtrl_Sub((Lock_Test_Mode_enum_t)testMode, data, dataLen);
		}
			break;
		default:
			
			break;
    }
}


/**
  * @brief  锁体休眠
  *         
  * @note   
  */
static void LockBig_Sleep(void)
{

}

/**
  * @brief  锁体任务函数
  *
  * @note
  *         
  * @param  event：当前任务的所有事件
  *
  * @return 返回未处理的事件
  */
static uint32_t LockBig_Task(uint32_t event)
{
	/* 系统启动事件 */
	if (event & EVENT_SYS_START)
	{
		LOCKBIG_LOG("Lock task start\r\n");
		Device_Enable(vPIN_C0);
		Device_Enable(vADC_1);
        LockBig_Start();
		return ( event ^ EVENT_SYS_START );
	}
	
	if (event & EVENT_SYS_MBOX)
    {
        uint8_t buffer[30] = {0};
        while (OSAL_MboxAccept(buffer))
        {
            LockBig_ProcessMbox(buffer);
        }
        return ( event ^ EVENT_SYS_MBOX );
    }
	
	/* 系统休眠事件 */
	if (event & EVENT_SYS_SLEEP)
	{
        LOCKBIG_LOG("Lock task sleep\r\n");
		Device_Disable(vPIN_C0);
		Device_Disable(vADC_1);
        LockBig_Sleep();
		return ( event ^ EVENT_SYS_SLEEP );
	}
	
	/* 系统中断事件 */
	if (event & EVENT_SYS_ISR)
	{
		LockBig_CounterIsr();
		return ( event ^ EVENT_SYS_ISR );
	}

    /* 电机监控事件 */
    if (event & EVENT_MOTOR_MONITOR)
	{
		LockBig_MotorMonitor();
        if (motorStatus.current != MOTOR_STA_IDLE)//非空闲状态下不允许休眠
        {
            OSAL_SetTaskStatus(TASK_STA_ACTIVE);
        }
        else
        {
            OSAL_SetTaskStatus(TASK_STA_NORMAL);
        }
        return ( event ^ EVENT_MOTOR_MONITOR );
    }
	return 0;
}
COMPONENT_TASK_EXPORT(COMP_LOCK, LockBig_Task, 4);
